<template>
  <div class="page-box">
    <!-- 配置层级选择器 -->
    <el-card class="level-selector-card" shadow="never">
      <div slot="header" class="card-header">
        <span>配置层级</span>
      </div>
      <el-radio-group v-model="configLevel" @change="handleConfigLevelChange">
        <el-radio-button label="global">全局配置</el-radio-button>
        <el-radio-button label="merchant">商户配置</el-radio-button>
        <el-radio-button label="campaign">活动配置</el-radio-button>
      </el-radio-group>

      <!-- 商户选择器 -->
      <div v-if="configLevel === 'merchant'" class="level-filter">
        <el-select v-model="selectedMerchantId" placeholder="选择商户" clearable filterable remote :remote-method="remoteSearchMerchants" :loading="merchantLoading" @change="handleMerchantChange">
          <el-option
            v-for="merchant in merchantList"
            :key="merchant.id"
            :label="`${merchant.merchant_name}（${merchant.contacts || '无联系人'}）`"
            :value="merchant.id">
          </el-option>
        </el-select>
      </div>

      <!-- 活动选择器 -->
      <div v-if="configLevel === 'campaign'" class="level-filter">
        <el-select v-model="selectedMerchantId" placeholder="选择商户" clearable filterable remote :remote-method="remoteSearchMerchants" :loading="merchantLoading" @change="handleMerchantChange">
          <el-option
            v-for="merchant in merchantList"
            :key="merchant.id"
            :label="`${merchant.merchant_name}（${merchant.contacts || '无联系人'}）`"
            :value="merchant.id">
          </el-option>
        </el-select>
        <el-select v-model="selectedCampaignId" placeholder="选择活动" clearable filterable remote :remote-method="remoteSearchCampaigns" :loading="campaignLoading" @change="handleCampaignChange" :disabled="!selectedMerchantId">
          <el-option
            v-for="campaign in campaignList"
            :key="campaign.id"
            :label="campaign.campaign_name || campaign.name"
            :value="campaign.id">
          </el-option>
        </el-select>
      </div>
    </el-card>

    <!-- 配置列表与操作 -->
    <el-card class="config-list-card">
      <div slot="header" class="card-header">
        <span>积分配置管理</span>
        <div class="header-actions">
          <el-button type="primary" icon="el-icon-plus" @click="handleAddConfig">
            添加配置
          </el-button>
          <el-button icon="el-icon-copy-document" @click="handleCopyConfig">
            复制配置
          </el-button>
          <el-button icon="el-icon-upload" @click="handleImportConfig">
            导入配置
          </el-button>
          <el-button type="success" icon="el-icon-check" @click="handleBatchEnable" :disabled="selectedConfigs.length === 0">
            批量启用
          </el-button>
          <el-button type="warning" icon="el-icon-close" @click="handleBatchDisable" :disabled="selectedConfigs.length === 0">
            批量禁用
          </el-button>
          <el-button icon="el-icon-download" @click="handleExportConfig">
            导出配置
          </el-button>
        </div>
      </div>

      <universal-table
        :key="`config-table-${configLevel}-${selectedMerchantId || 0}-${selectedCampaignId || 0}`"
        :columns="configColumns"
        :fetch-data="fetchConfigData"
        permission-prefix="sys:nfc_points_config"
        :show-selection="true"
        :show-index="true"
        :show-operation="true"
        :operation-width="'220'"
        :bt1-name="''"
        :bt2-name="''"
        :show-export="false"
        :export-file-name="''"
        :init-search-form="{}"
        :custom-export="false"
        :show-keyword-search="false"
        :show-date-range="false"
        @edit="handleEditConfig"
        @delete="handleDeleteConfig"
        @reset="resetSearch"
        @selection-change="handleSelectionChange"
        @status-change="handleStatusChange"
        ref="configTable">

        <!-- 搜索区域扩展 -->
        <template #searchExtend>
          <el-form-item prop="config_type">
            <el-select v-model="searchForm.config_type" placeholder="配置类型" clearable style="width: 120px;">
              <el-option label="注册奖励" value="register_reward"></el-option>
              <el-option label="推荐奖励" value="referral_reward"></el-option>
              <el-option label="消费奖励" value="consumption_reward"></el-option>
              <el-option label="签到奖励" value="checkin_reward"></el-option>
              <el-option label="分享奖励" value="share_reward"></el-option>
              <el-option label="评价奖励" value="review_reward"></el-option>
            </el-select>
          </el-form-item>

          <el-form-item prop="status">
            <el-select v-model="searchForm.status" placeholder="状态" clearable style="width: 80px;">
              <el-option label="启用" value="1"></el-option>
              <el-option label="禁用" value="0"></el-option>
            </el-select>
          </el-form-item>

          <el-form-item prop="effective_date">
            <el-date-picker
              v-model="effectiveDateRange"
              type="daterange"
              range-separator="至"
              start-placeholder="生效时间"
              end-placeholder="失效时间"
              value-format="yyyy-MM-dd"
              @change="handleEffectiveDateRangeChange">
            </el-date-picker>
          </el-form-item>


          <!-- 刷新按钮 -->
          <el-form-item>
            <el-button type="primary" @click="handleRefresh" title="刷新">
              <i class="el-icon-refresh"></i>
            </el-button>
          </el-form-item>
        </template>

        <!-- 操作栏扩展 -->
        <template #operationExtend="{ row }">
          <el-tooltip content="查看详情" placement="top">
            <el-button size="mini" type="info" icon="el-icon-view" @click="handleViewConfig(row)" circle></el-button>
          </el-tooltip>
          <el-tooltip content="复制配置" placement="top">
            <el-button size="mini" type="warning" icon="el-icon-copy-document" @click="handleCopyConfigItem(row)" circle></el-button>
          </el-tooltip>
          <el-tooltip content="验证规则" placement="top">
            <el-button size="mini" type="success" icon="el-icon-check" @click="handleValidateConfig(row)" circle></el-button>
          </el-tooltip>
        </template>
      </universal-table>
    </el-card>

    <!-- 配置编辑对话框 -->
    <el-dialog :title="configDialogTitle" :visible.sync="configDialogVisible" width="900px" @close="resetConfigForm">

      <el-form :model="configForm" :rules="configRules" ref="configForm" label-width="120px">
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="配置名称" prop="config_name">
              <el-input v-model="configForm.config_name" placeholder="请输入配置名称"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="配置类型" prop="config_type">
              <el-select v-model="configForm.config_type" placeholder="请选择配置类型">
                <el-option label="注册奖励" value="register_reward"></el-option>
                <el-option label="推荐奖励" value="referral_reward"></el-option>
                <el-option label="消费奖励" value="consumption_reward"></el-option>
                <el-option label="签到奖励" value="checkin_reward"></el-option>
                <el-option label="分享奖励" value="share_reward"></el-option>
                <el-option label="评价奖励" value="review_reward"></el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="生效时间" prop="effective_time">
              <el-date-picker
                v-model="configForm.effective_time"
                type="datetime"
                placeholder="选择生效时间"
                value-format="yyyy-MM-dd HH:mm:ss">
              </el-date-picker>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="失效时间" prop="expiry_time">
              <el-date-picker
                v-model="configForm.expiry_time"
                type="datetime"
                placeholder="选择失效时间"
                value-format="yyyy-MM-dd HH:mm:ss">
              </el-date-picker>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="优先级" prop="priority">
              <span slot="label">优先级
                <el-tooltip content="同层级冲突时，数字越大越优先" placement="top">
                  <i class="el-icon-info"></i>
                </el-tooltip>
              </span>
              <el-input-number v-model="configForm.priority" :min="0" :max="100" placeholder="0-100"></el-input-number>
              <div class="form-tip">同层级冲突时按数值比较，数字越大越优先。</div>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="基础积分" prop="base_points">
              <span slot="label">基础积分
                <el-tooltip content="触发时的基础积分值" placement="top">
                  <i class="el-icon-info"></i>
                </el-tooltip>
              </span>
              <el-input-number v-model="configForm.base_points" :min="0" placeholder="基础积分数量"></el-input-number>
              <div class="form-tip">单位：积分。与倍率组合使用。</div>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="状态">
              <el-switch v-model="configForm.status" :active-value="1" :inactive-value="0"></el-switch>
            </el-form-item>
          </el-col>
        </el-row>

        <!-- 积分规则配置 -->
        <el-divider content-position="left">积分规则配置</el-divider>

        <el-form-item label="积分倍率" prop="points_multiplier">
          <span slot="label">积分倍率
            <el-tooltip content="最终积分 = 基础积分 × 积分倍率" placement="top">
              <i class="el-icon-info"></i>
            </el-tooltip>
          </span>
          <el-input-number v-model="configForm.points_multiplier" :min="0" :step="0.1" :precision="2" placeholder="积分倍率"></el-input-number>
          <div class="form-tip">示例：基础积分10、倍率1.5 → 最终积分15。</div>
        </el-form-item>
        <el-form-item label="最大积分" prop="max_points">
          <span slot="label">最大积分
            <el-tooltip content="单次触发可获得的最高积分，0 表示不限制" placement="top">
              <i class="el-icon-info"></i>
            </el-tooltip>
          </span>
          <el-input-number v-model="configForm.max_points" :min="0" placeholder="单次最大积分（0为不限制）"></el-input-number>
        </el-form-item>

        <el-form-item label="每日限制" prop="daily_limit">
          <span slot="label">每日限制
            <el-tooltip content="同一主体每天可获得的积分上限，0 表示不限制" placement="top">
              <i class="el-icon-info"></i>
            </el-tooltip>
          </span>
          <el-input-number v-model="configForm.daily_limit" :min="0" placeholder="每日积分上限（0为不限制）"></el-input-number>
        </el-form-item>




        <!-- 条件规则配置 -->
        <el-divider content-position="left">条件规则配置</el-divider>

        <el-form-item label="条件规则">
          <el-button type="primary" size="small" @click="handleAddCondition">添加条件</el-button>
        </el-form-item>

        <div class="condition-rules">
          <div
            v-for="(condition, index) in configForm.condition_rules"
            :key="index"
            class="condition-item">
            <el-row :gutter="10">
              <el-col :span="6">
                <el-select v-model="condition.field" placeholder="字段">
                  <el-option label="消费金额" value="amount"></el-option>
                  <el-option label="用户等级" value="user_level"></el-option>
                  <el-option label="注册天数" value="register_days"></el-option>
                  <el-option label="消费次数" value="order_count"></el-option>
                </el-select>
              </el-col>
              <el-col :span="4">
                <el-select v-model="condition.operator" placeholder="操作符">
                  <el-option label="等于" value="eq"></el-option>
                  <el-option label="大于" value="gt"></el-option>
                  <el-option label="大于等于" value="gte"></el-option>
                  <el-option label="小于" value="lt"></el-option>
                  <el-option label="小于等于" value="lte"></el-option>
                  <el-option label="在范围内" value="between"></el-option>
                </el-select>
              </el-col>
              <el-col :span="6">
                <el-input v-model="condition.value" placeholder="值"></el-input>
              </el-col>
              <el-col :span="6">
                <el-input v-model="condition.description" placeholder="条件描述"></el-input>
              </el-col>
              <el-col :span="2">
                <el-button type="danger" size="small" icon="el-icon-delete" @click="handleRemoveCondition(index)"></el-button>
              </el-col>
            </el-row>
          </div>
        </div>

        <el-form-item label="配置描述" prop="description">
          <el-input
            v-model="configForm.description"
            type="textarea"
            :rows="3"
            placeholder="请输入配置描述"
            maxlength="500"
            show-word-limit>
          </el-input>
        </el-form-item>

        <el-form-item label="配置备注" prop="remark">
          <el-input
            v-model="configForm.remark"
            type="textarea"
            :rows="2"
            placeholder="请输入配置备注"
            maxlength="200"
            show-word-limit>
          </el-input>
        </el-form-item>
      </el-form>

      <div slot="footer" class="dialog-footer">
        <el-button @click="configDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleValidateConfigForm">验证规则</el-button>
        <el-button type="success" @click="confirmSaveConfig" :loading="saveConfigLoading">保存配置</el-button>
      </div>
    </el-dialog>

    <!-- 复制配置对话框 -->
    <el-dialog title="复制配置" :visible.sync="copyConfigDialogVisible" width="500px" @close="resetCopyConfigForm">
      <el-form :model="copyConfigForm" :rules="copyConfigRules" ref="copyConfigForm" label-width="120px">
        <el-form-item label="目标层级" prop="target_level">
          <el-select v-model="copyConfigForm.target_level" placeholder="选择目标层级" @change="handleCopyTargetLevelChange">
            <el-option label="全局配置" value="global"></el-option>
            <el-option label="商户配置" value="merchant"></el-option>
            <el-option label="活动配置" value="campaign"></el-option>
          </el-select>
        </el-form-item>

        <el-form-item label="新配置名称" prop="new_config_name">
          <el-input v-model="copyConfigForm.new_config_name" placeholder="请输入新配置名称"></el-input>
        </el-form-item>

        <el-form-item label="目标商户" prop="target_merchant_id" v-if="['merchant', 'campaign'].includes(copyConfigForm.target_level)">
          <el-select v-model="copyConfigForm.target_merchant_id" placeholder="选择目标商户" clearable filterable remote :remote-method="remoteSearchTargetMerchants" :loading="targetMerchantLoading" @change="handleCopyTargetMerchantChange">
            <el-option
              v-for="merchant in targetMerchantList"
              :key="merchant.id"
              :label="`${merchant.merchant_name}（${merchant.contacts || '无联系人'}）`"
              :value="merchant.id">
            </el-option>
          </el-select>
        </el-form-item>

        <el-form-item label="目标活动" prop="target_campaign_id" v-if="copyConfigForm.target_level === 'campaign'">
          <el-select v-model="copyConfigForm.target_campaign_id" placeholder="选择目标活动" clearable filterable remote :remote-method="remoteSearchTargetCampaigns" :loading="targetCampaignLoading" :disabled="!copyConfigForm.target_merchant_id">
            <el-option
              v-for="campaign in targetCampaignList"
              :key="campaign.id"
              :label="campaign.campaign_name || campaign.name"
              :value="campaign.id">
            </el-option>
          </el-select>
        </el-form-item>

        <el-form-item label="是否覆盖">
          <el-switch v-model="copyConfigForm.overwrite" :active-text="'覆盖已有配置'" :inactive-text="'保留已有配置'"></el-switch>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="copyConfigDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="confirmCopyConfig" :loading="copyConfigLoading">确定复制</el-button>
      </div>
    </el-dialog>

    <!-- 导入配置对话框 -->
    <el-dialog title="导入配置" :visible.sync="importConfigDialogVisible" width="640px">
      <div class="upload-content">
        <el-alert title="上传说明" type="info" :closable="false" show-icon>
          <template #description>
            <div>
              <p>· 仅支持 CSV 文件，大小不超过 2MB</p>
              <p>· CSV 必须包含表头：配置名称, 配置类型, 基础积分, 积分倍率, 最大积分, 每日限制, 优先级, 生效时间, 失效时间, 描述, 备注</p>
            </div>
          </template>
        </el-alert>

        <el-upload
          ref="upload"
          class="upload-demo"
          drag
          :action="uploadAction"
          :headers="uploadHeaders"
          :on-success="handleUploadSuccess"
          :on-error="handleUploadError"
          :on-change="handleFileChange"
          :on-remove="handleFileRemove"
          :before-upload="beforeUpload"
          :file-list="uploadFileList"
          :limit="1"
          :auto-upload="false"
          accept=".csv">
          <i class="el-icon-upload"></i>
          <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
          <div class="el-upload__tip" slot="tip">只支持上传CSV文件，且不超过2MB</div>
        </el-upload>

        <!-- 上传结果 -->
        <div v-if="uploadResult" class="upload-result">
          <el-alert
            :title="`上传结果：成功 ${uploadResult.success_count || 0} 条，失败 ${uploadResult.failed_count || uploadResult.fail_count || 0} 条`"
            :type="(uploadResult.failed_count || uploadResult.fail_count || 0) > 0 ? 'warning' : 'success'"
            :closable="false">
          </el-alert>
          <div v-if="uploadResult.errors && uploadResult.errors.length > 0" class="upload-errors">
            <p><strong>错误详情：</strong></p>
            <ul>
              <li v-for="(error, index) in uploadResult.errors" :key="index">{{ error }}</li>
            </ul>
          </div>
        </div>
      </div>

      <span slot="footer" class="dialog-footer">
        <el-button @click="importConfigDialogVisible = false">取消</el-button>
        <el-button @click="handleDownloadTemplate">下载模板</el-button>
        <el-button type="primary" @click="submitUpload" :loading="uploading">确定上传</el-button>
      </span>
    </el-dialog>

    <!-- 配置模板对话框 -->
    <el-dialog title="配置模板" :visible.sync="templateDialogVisible" width="800px">
      <div class="template-list">
        <el-row :gutter="20">
          <el-col :span="8" v-for="template in configTemplates" :key="template.id">
            <el-card class="template-card" shadow="hover" @click.native="handleApplyTemplate(template)">
              <div class="template-header">
                <h4>{{ template.name }}</h4>
                <el-tag :type="template.type_tag">{{ template.type_text }}</el-tag>
              </div>
              <div class="template-description">
                {{ template.description }}
              </div>
              <div class="template-config">
                <span>基础积分：{{ template.base_points }}</span>
                <span>积分倍率：{{ template.points_multiplier }}</span>
              </div>
            </el-card>
          </el-col>
        </el-row>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button @click="templateDialogVisible = false">关闭</el-button>
      </div>

    </el-dialog>

  </div>
</template>

<script>
import { nfcPointsConfigAPI, getMerchantList, searchMerchants } from '@/api/nfc'
import { handleCSVExportResponse } from '@/utils/exportCSV'
import UniversalTable from '@/components/TableComponent.vue'

export default {
  name: 'NfcPointsConfig',
  components: {
    UniversalTable
  },
  data() {
    return {
      configLevel: 'global',
      selectedMerchantId: '',
      selectedCampaignId: '',

      // 列表数据
      merchantList: [],
      campaignList: [],
      targetCampaignList: [],
      targetMerchantList: [],
      configTemplates: [],

      // 远程搜索与加载状态
      merchantLoading: false,
      campaignLoading: false,
      targetCampaignLoading: false,
      targetMerchantLoading: false,
      merchantKeyword: '',
      campaignKeyword: '',
      targetCampaignKeyword: '',
      targetMerchantKeyword: '',
      merchantPage: 1,
      campaignPage: 1,
      campaignLimit: 50,
      targetCampaignPage: 1,
      targetCampaignLimit: 50,
      merchantLimit: 50,
      targetMerchantPage: 1,
      targetMerchantLimit: 50,




      // 表格配置
      configColumns: [
        { prop: 'id', label: '配置ID', width: 80 },
        { prop: 'config_name', label: '配置名称', width: 150 },
        {
          prop: 'config_type_text',
          label: '配置类型',
          width: 120
        },
        { prop: 'merchant_name', label: '商户名称', width: 120 },
        // 活动配置层级，插入活动名称列
        ...(this.configLevel === 'campaign' ? [{ prop: 'campaign_name', label: '活动名称', width: 180 }] : []),

        { prop: 'base_points', label: '基础积分', width: 100 },
        { prop: 'points_multiplier', label: '积分倍率', width: 100 },
        { prop: 'max_points', label: '最大积分', width: 100 },
        { prop: 'daily_limit', label: '每日限制', width: 100 },
        { prop: 'priority', label: '优先级', width: 80 },
        {
          prop: 'status',
          label: '状态',
          width: 80
        },
        { prop: 'effective_time', label: '生效时间', width: 160 },
        { prop: 'expiry_time', label: '失效时间', width: 160 },
        { prop: 'create_time', label: '创建时间', width: 160 }
      ],

      // 搜索表单
      searchForm: {
        config_type: '',
        status: '',
        effective_start: '',
        effective_end: ''
      },
      effectiveDateRange: null,

      // 配置表单
      configDialogVisible: false,
      configDialogTitle: '添加配置',

      configForm: {
        id: '',
        config_name: '',
        config_type: '',
        base_points: 0,
        points_multiplier: 1.0,
        max_points: 0,
        daily_limit: 0,
        priority: 1,
        status: 1,
        effective_time: '',
        expiry_time: '',
        condition_rules: [],
        description: '',
        remark: ''
      },
      configRules: {
        config_name: [
          { required: true, message: '请输入配置名称', trigger: 'blur' }
        ],
        config_type: [
          { required: true, message: '请选择配置类型', trigger: 'change' }
        ],
        base_points: [
          { required: true, message: '请输入基础积分', trigger: 'blur' }
        ],
        points_multiplier: [
          { required: true, message: '请输入积分倍率', trigger: 'blur' }
        ],
        effective_time: [
          { required: true, message: '请选择生效时间', trigger: 'change' }
        ]
      },
      saveConfigLoading: false,

      // 复制配置对话框
      copyConfigDialogVisible: false,
      copyConfigForm: {
        source_config_id: '',
        target_level: '',
        new_config_name: '',
        target_merchant_id: '',
        target_campaign_id: '',
        overwrite: false
      },
      copyConfigRules: {
        target_level: [
          { required: true, message: '请选择目标层级', trigger: 'change' }
        ],
        new_config_name: [
          { required: true, message: '请输入新配置名称', trigger: 'blur' }
        ]
      },
      copyConfigLoading: false,

      // 导入配置对话框
      importConfigDialogVisible: false,

      // 直传上传配置（完全对齐 merchant-coupon）
      uploadDialogVisible: false,
      uploadAction: '',
      uploadHeaders: {},
      uploadFileList: [],
      uploading: false,

      // 配置模板对话框
      templateDialogVisible: false,

      // 选择项
      selectedConfigs: []
    }
  },
  watch: {
    // 监听配置级别变化
    configLevel: {
      handler(newLevel, oldLevel) {
        console.log(`配置级别变化: ${oldLevel} -> ${newLevel}`)
        // 动态key机制会自动重新渲染组件，这里可以添加额外的逻辑
      },
      immediate: false
    },

    // 监听商户ID变化
    selectedMerchantId: {
      handler(newId, oldId) {
        console.log(`选中商户ID变化: ${oldId} -> ${newId}`)
      },
      immediate: false
    },

    // 监听活动ID变化
    selectedCampaignId: {
      handler(newId, oldId) {
        console.log(`选中活动ID变化: ${oldId} -> ${newId}`)
      },
      immediate: false
    }
  },
  mounted() {
    this.loadMerchantList()
    this.loadConfigTemplates()
    // 初始化商户远程搜索数据
    this.remoteSearchMerchants('')
  },
  methods: {
    // 远程搜索商户（主要）
    async remoteSearchMerchants(query) {
      try {
        this.merchantLoading = true
        this.merchantKeyword = query || ''
        const params = { keyword: this.merchantKeyword, page: this.merchantPage, limit: this.merchantLimit }
        const res = await searchMerchants(params)
        if (res && (res.code === 0 || res.code === 200)) {
          const list = res.data?.list || res.data || []
          this.merchantList = Array.isArray(list) ? list : []
        }
      } catch (e) {
        console.error('远程搜索商户失败', e)
      } finally {
        this.merchantLoading = false
      }
    },

    // 远程搜索目标商户（复制配置）
    async remoteSearchTargetMerchants(query) {
      try {
        this.targetMerchantLoading = true
        this.targetMerchantKeyword = query || ''
        const params = { keyword: this.targetMerchantKeyword, page: this.targetMerchantPage, limit: this.targetMerchantLimit }
        const res = await searchMerchants(params)
        if (res && (res.code === 0 || res.code === 200)) {
          const list = res.data?.list || res.data || []
          this.targetMerchantList = Array.isArray(list) ? list : []
        }
      } catch (e) {
        console.error('远程搜索目标商户失败', e)
      } finally {
        this.targetMerchantLoading = false
      }
    },

    // 远程搜索活动（活动配置）
    async remoteSearchCampaigns(query) {
      try {
        this.campaignLoading = true
        this.campaignKeyword = query || ''
        const params = { keyword: this.campaignKeyword, page: this.campaignPage, limit: this.campaignLimit }
        if (this.selectedMerchantId) params.merchant_id = this.selectedMerchantId
        const res = await this.$httpRequest({ url: 'nfc/campaigns', method: 'get', params })
        if (res && (res.code === 0 || res.code === 200)) {
          const list = res.data?.list || res.data || []
          this.campaignList = Array.isArray(list) ? list : []
        }
      } catch (e) {
        console.error('远程搜索活动失败', e)
      } finally {
        this.campaignLoading = false
      }
    },

    // 远程搜索目标活动（复制配置）
    async remoteSearchTargetCampaigns(query) {
      try {
        this.targetCampaignLoading = true
        this.targetCampaignKeyword = query || ''
        const params = { keyword: this.targetCampaignKeyword, page: this.targetCampaignPage, limit: this.targetCampaignLimit }
        if (this.copyConfigForm.target_merchant_id) params.merchant_id = this.copyConfigForm.target_merchant_id
        const res = await this.$httpRequest({ url: 'nfc/campaigns', method: 'get', params })
        if (res && (res.code === 0 || res.code === 200)) {
          const list = res.data?.list || res.data || []
          this.targetCampaignList = Array.isArray(list) ? list : []
        }
      } catch (e) {
        console.error('远程搜索目标活动失败', e)
      } finally {
        this.targetCampaignLoading = false
      }
    },

    // 加载商户列表
    async loadMerchantList() {
      try {
        this.merchantList = []
        const res = await getMerchantList()
        // 后端返回：code=0, data=[{id, merchant_name, contacts}]
        if (res && (res.code === 0 || res.code === 200)) {
          this.merchantList = Array.isArray(res.data) ? res.data : []
        } else {
          this.$message.error(res?.message || '获取商户列表失败')
        }
      } catch (error) {
        console.error('加载商户列表失败：', error)
        this.$message.error('加载商户列表失败')
      }
    },

    // 加载活动列表
    async loadCampaignList(merchantId) {
      try {
        this.campaignList = []
        // 复用后端分页接口，取前若干条（或可加分页弹窗选择）
        const params = { keyword: '', page: 1, limit: 50 }
        if (merchantId) params.merchant_id = merchantId
        const res = await this.$httpRequest({ url: 'nfc/campaigns', method: 'get', params })
        if (res && (res.code === 0 || res.code === 200)) {
          const list = res.data?.list || res.data || []
          this.campaignList = Array.isArray(list) ? list : []
        } else {
          this.$message.error(res?.message || '获取活动列表失败')
        }
      } catch (error) {
        console.error('加载活动列表失败：', error)
        this.$message.error('加载活动列表失败')
      }
    },

    // 加载配置模板
    async loadConfigTemplates() {
      try {
        const response = await nfcPointsConfigAPI.getConfigTemplates()
        this.configTemplates = response.data || []
      } catch (error) {
        console.warn('加载配置模板失败，使用默认模板：', error.message)
        // 提供默认模板数据，避免页面崩溃
        this.configTemplates = [
          {
            id: 1,
            name: '基础积分配置',
            description: '基础的积分获取配置模板',
            config_type: 'basic',
            base_points: 10,
            points_multiplier: 1.0,
            max_points: 1000
          },
          {
            id: 2,
            name: '高级积分配置',
            description: '包含倍率和限制的高级配置模板',
            config_type: 'advanced',
            base_points: 20,
            points_multiplier: 1.5,
            max_points: 2000
          }
        ]
      }
    },

    // 配置层级变化
    handleConfigLevelChange() {
      this.selectedMerchantId = ''
      this.selectedCampaignId = ''
      // 移除 handleRefresh() 调用，让动态key机制自动处理组件重新渲染
    },

    // 商户变化
    handleMerchantChange() {
      this.selectedCampaignId = ''
      if (this.selectedMerchantId) {
        this.loadCampaignList(this.selectedMerchantId)
      }
      // 移除 handleRefresh() 调用，让动态key机制自动处理组件重新渲染
    },

    // 活动变化
    handleCampaignChange() {
      // 移除 handleRefresh() 调用，让动态key机制自动处理组件重新渲染
    },

    // 获取配置数据
    async fetchConfigData(params) {
      try {
        const searchParams = {
          ...params,
          ...this.searchForm,
          level: this.configLevel,
          merchant_id: this.selectedMerchantId,
          campaign_id: this.selectedCampaignId
        }

        console.log('🚀 fetchConfigData调用 - 请求参数:', searchParams)
        console.log('📊 当前状态:', {
          configLevel: this.configLevel,
          selectedMerchantId: this.selectedMerchantId,
          selectedCampaignId: this.selectedCampaignId
        })

        const response = await nfcPointsConfigAPI.getConfigList(searchParams)

        console.log('✅ API响应:', {
          code: response.code,
          message: response.message,
          dataCount: response.data ? response.data.length : 0,
          total: response.count
        })

        const result = {
          list: response.data || [],  // 修改为 list，匹配 universal-table 组件期望
          total: response.count || 0
        }

        console.log('📋 返回给表格的数据:', result)
        return result
      } catch (error) {
        console.error('❌ 获取配置数据失败:', error)
        // 返回空数据避免表格组件出错
        const emptyResult = {
          list: [],  // 修改为 list
          total: 0
        }
        console.log('📋 返回空数据:', emptyResult)
        return emptyResult
      }
    },

    // 处理日期范围变化（生效）
    handleEffectiveDateRangeChange(value) {
      if (value && value.length === 2) {
        this.searchForm.effective_start = value[0]
        this.searchForm.effective_end = value[1]
      } else {
        this.searchForm.effective_start = ''
        this.searchForm.effective_end = ''
      }
      this.handleRefresh()
    },


    // 添加配置
    handleAddConfig() {
      this.configDialogTitle = '添加配置'
      this.resetConfigForm()
      this.configDialogVisible = true
    },

    // 编辑配置
    async handleEditConfig(row) {
      this.configDialogTitle = '编辑配置'
      try {
        const response = await nfcPointsConfigAPI.getConfigInfo(row.id)
        this.configForm = {
          ...response.data,
          condition_rules: response.data.condition_rules || []
        }
        this.configDialogVisible = true
      } catch (error) {
        this.$message.error('获取配置详情失败：' + error.message)
      }
    },

    // 查看配置详情
    handleViewConfig(row) {
      this.handleEditConfig(row)
    },

    // 删除配置
    handleDeleteConfig(row) {
      this.$confirm('确定要删除这个配置吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async () => {
        try {
          const result = await nfcPointsConfigAPI.deleteConfig({ config_id: row.id })
          if (result.code === 0) {
            this.$message.success(result.msg || '删除成功')
            this.handleRefresh()
          } else {
            this.$message.error(result.message || result.msg || '删除失败')
          }
        } catch (error) {
          this.$message.error('删除失败：' + error.message)
        }
      })
    },

    // 验证配置
    async handleValidateConfig(row) {
      try {
        const response = await nfcPointsConfigAPI.validateConfigRules({
          config_id: row.id
        })
        if (response.data.valid) {
          this.$message.success('配置验证通过')
        } else {
          this.$message.error('配置验证失败：' + (response.data.message || ''))
        }
      } catch (error) {
        this.$message.error('验证失败：' + error.message)
      }
    },

    // 验证表单配置
    async handleValidateConfigForm() {
      if (!this.configForm.config_name || !this.configForm.config_type) {
        this.$message.warning('请先填写基本配置信息')
        return
      }

      try {
        const response = await nfcPointsConfigAPI.validateConfigRules({
          config_data: this.configForm
        })
        if (response.data.valid) {
          this.$message.success('配置规则验证通过')
        } else {
          this.$message.error('配置规则验证失败：' + (response.data.message || ''))
        }
      } catch (error) {
        this.$message.error('验证失败：' + error.message)
      }
    },

    // 保存配置
    async confirmSaveConfig() {
      this.$refs.configForm.validate(async (valid) => {
        if (valid) {
          this.saveConfigLoading = true
          try {
            const params = {
              ...this.configForm,
              level: this.configLevel,
              merchant_id: this.selectedMerchantId,
              campaign_id: this.selectedCampaignId
            }
            const result = await nfcPointsConfigAPI.saveConfig(params)
            if (result.code === 0) {
              this.$message.success(result.msg || '保存成功')
              this.configDialogVisible = false
              this.handleRefresh()
            } else {
              // 显示具体的错误信息
              let errorMessage = result.message || result.msg || '保存失败'
              this.$message.error(errorMessage)
            }
          } catch (error) {
            this.$message.error('保存失败：' + error.message)
          } finally {
            this.saveConfigLoading = false
          }
        }
      })
    },

    // 复制配置
    handleCopyConfig() {
      if (this.selectedConfigs.length === 0) {
        this.$message.warning('请先选择要复制的配置')
        return
      }
      const sourceConfig = this.selectedConfigs[0]
      this.copyConfigForm.source_config_id = sourceConfig.id
      // 生成默认配置名称
      this.copyConfigForm.new_config_name = this.generateDefaultConfigName(sourceConfig.config_name || '配置')
      this.copyConfigDialogVisible = true
    },

    // 复制单个配置
    handleCopyConfigItem(row) {
      this.copyConfigForm.source_config_id = row.id
      // 生成默认配置名称
      this.copyConfigForm.new_config_name = this.generateDefaultConfigName(row.config_name || '配置')
      this.copyConfigDialogVisible = true
    },

    // 复制目标层级变化
    handleCopyTargetLevelChange() {
      this.copyConfigForm.target_merchant_id = ''
      this.copyConfigForm.target_campaign_id = ''
      this.targetCampaignList = []
      this.targetMerchantList = []
    },

    // 复制目标商户变化
    handleCopyTargetMerchantChange() {
      this.copyConfigForm.target_campaign_id = ''
      if (this.copyConfigForm.target_merchant_id) {
        this.loadTargetCampaignList(this.copyConfigForm.target_merchant_id)
      }
    },

    // 加载目标活动列表
    async loadTargetCampaignList(merchantId) {
      try {
        this.targetCampaignList = []
        const params = { keyword: '', page: 1, limit: 50 }
        if (merchantId) params.merchant_id = merchantId
        const res = await this.$httpRequest({ url: 'nfc/campaigns', method: 'get', params })
        if (res && (res.code === 0 || res.code === 200)) {
          const list = res.data?.list || res.data || []
          this.targetCampaignList = Array.isArray(list) ? list : []
        } else {
          this.$message.error(res?.message || '获取目标活动列表失败')
        }
      } catch (error) {
        console.error('加载目标活动列表失败：', error)
        this.$message.error('获取目标活动列表失败')
      }
    },

    // 确认复制配置
    async confirmCopyConfig() {
      this.$refs.copyConfigForm.validate(async (valid) => {
        if (valid) {
          this.copyConfigLoading = true
          try {
            const result = await nfcPointsConfigAPI.copyConfig(this.copyConfigForm)
            if (result.code === 0) {
              this.$message.success(result.msg || '复制成功')
              this.copyConfigDialogVisible = false
              this.handleRefresh()
            } else {
              this.$message.error(result.message || result.msg || '复制失败')
            }
          } catch (error) {
            this.$message.error('复制失败：' + error.message)
          } finally {
            this.copyConfigLoading = false
          }
        }
      })
    },

    // 导入配置
    handleImportConfig() {
      // 打开对话框并准备直传配置
      this.setupUploadConfig()
      this.importConfigDialogVisible = true
    },

    // 与 merchant-coupon 一致：构造上传 action 与 headers
    setupUploadConfig() {
      const baseUrl = this.$httpRequest.instance.defaults.baseURL || process.env.VUE_APP_API_BASE_URL
      const level = this.configLevel || 'global'
      const merchantId = this.selectedMerchantId || ''
      const campaignId = this.selectedCampaignId || ''
      const params = new URLSearchParams()
      params.set('level', level)
      if (merchantId) params.set('merchant_id', merchantId)
      if (campaignId) params.set('campaign_id', campaignId)
      this.uploadAction = `${baseUrl}/nfc/points/config/import?${params.toString()}`

      const token = this.$store.getters.token
      this.uploadHeaders = token ? { 'Authorization': token } : {}
      this.uploadFileList = []
    },

    // 上传前处理
    // 与 merchant-coupon 对齐：仅CSV，直传，由el-upload提交
    beforeUpload(file) {
      const isCsv = file.type === 'text/csv' || file.name.toLowerCase().endsWith('.csv')
      const isLt2M = file.size / 1024 / 1024 < 2
      if (!isCsv) {
        this.$message.error('只能上传CSV文件!')
        return false
      }
      if (!isLt2M) {
        this.$message.error('上传文件大小不能超过2MB!')
        return false
      }
      return true
    },

    // 文件选择变化
    handleFileChange(file, fileList) {
      this.uploadFileList = fileList
    },

    // 文件移除
    handleFileRemove(file, fileList) {
      this.uploadFileList = fileList
    },

    // 提交上传（直传）
    submitUpload() {
      if (!this.uploadFileList.length) {
        this.$message.warning('请选择要上传的CSV文件')
        return
      }
      this.uploading = true
      this.$nextTick(() => {
        if (this.$refs.upload) {
          this.$refs.upload.submit()
        }
      })
    },

    // 上传成功处理
    // eslint-disable-next-line no-unused-vars
    handleUploadSuccess(response, file, fileList) {
      this.$message.success('配置导入成功！')
      this.importConfigDialogVisible = false
      this.handleRefresh()
    },

    // 上传失败处理
    // eslint-disable-next-line no-unused-vars
    handleUploadError(error, file, fileList) {
      console.error('上传失败：', error)
      this.$message.error('配置导入失败，请检查文件格式！')
    },

    // 下载模板
    async handleDownloadTemplate() {
      try {
        const response = await nfcPointsConfigAPI.downloadTemplate({ format: 'csv' })
        const result = handleCSVExportResponse(response, '积分配置导入模板.csv')
        if (result.success) {
          this.$message.success('模板下载成功')
        } else {
          throw new Error(result.error)
        }
      } catch (error) {
        console.error('下载模板失败', error)
        this.$message.error('模板下载失败：' + (error.message || '未知错误'))
      }
    },

    // 导出配置（智能模式选择 - 按commission页面方式）
    async handleExportConfig() {
      try {
        // 构建导出参数，默认导出筛选结果
        const exportParams = {
          mode: 'filter',
          level: this.configLevel,
          merchant_id: this.selectedMerchantId,
          campaign_id: this.selectedCampaignId,
          ...this.searchForm
        }

        // 如果有选中数据，提示用户选择导出方式
        if (this.selectedConfigs && this.selectedConfigs.length > 0) {
          const action = await this.$confirm(
            `检测到已选中 ${this.selectedConfigs.length} 条记录，请选择导出方式：`,
            '选择导出方式',
            {
              confirmButtonText: '导出选中记录',
              cancelButtonText: '导出筛选结果',
              distinguishCancelAndClose: true,
              type: 'info'
            }
          ).then(() => 'selected').catch(action => {
            if (action === 'cancel') return 'filter'
            return null // 关闭对话框
          })

          if (!action) return // 用户关闭弹窗
          if (action === 'selected') {
            exportParams.mode = 'selected'
            exportParams.ids = this.selectedConfigs.map(row => row.id)
          }
        }

        // 调用导出API
        this.$message.info('正在生成CSV文件，请稍候...')
        const response = await nfcPointsConfigAPI.exportConfig(exportParams)

        // 处理下载，统一使用工具方法
        const result = handleCSVExportResponse(response, 'NFC积分配置.csv')
        if (result.success) {
          this.$message.success(`导出成功：${result.filename}`)
        } else {
          throw new Error(result.error)
        }
      } catch (error) {
        console.error('CSV导出失败:', error)
        
        // 详细错误处理
        let errorMessage = '导出失败'
        if (error && error.message && error.message.includes('cancel')) {
          // 用户点了取消键，按筛选结果导出逻辑已处理；这里主要防止误报
          return
        }
        if (error.response) {
          if (error.response.data && error.response.data.message) {
            errorMessage = error.response.data.message
          } else {
            errorMessage = `服务器错误: ${error.response.status}`
          }
        } else if (error.message) {
          errorMessage = error.message
        }
        this.$message.error(errorMessage)
      }
    },


    // 添加条件
    handleAddCondition() {
      this.configForm.condition_rules.push({
        field: '',
        operator: '',
        value: '',
        description: ''
      })
    },

    // 移除条件
    handleRemoveCondition(index) {
      this.configForm.condition_rules.splice(index, 1)
    },

    // 应用模板
    handleApplyTemplate(template) {
      this.configForm = {
        ...this.configForm,
        config_name: template.name,
        config_type: template.config_type,
        base_points: template.base_points,
        points_multiplier: template.points_multiplier,
        max_points: template.max_points,
        daily_limit: template.daily_limit,
        condition_rules: template.condition_rules || [],
        description: template.description
      }
      this.templateDialogVisible = false
      this.configDialogVisible = true
    },

    // 选择变化
    handleSelectionChange(selection) {
      this.selectedConfigs = selection
    },

    // 工具方法
    getConfigTypeText(type) {
      const typeMap = {
        'register_reward': '注册奖励',
        'referral_reward': '推荐奖励',
        'consumption_reward': '消费奖励',
        'checkin_reward': '签到奖励',
        'share_reward': '分享奖励',
        'review_reward': '评价奖励'
      }
      return typeMap[type] || type
    },

    // 重置表单
    resetConfigForm() {
      this.$refs.configForm && this.$refs.configForm.resetFields()
      this.configForm = {
        id: '',
        config_name: '',
        config_type: '',
        base_points: 0,
        points_multiplier: 1.0,
        max_points: 0,
        daily_limit: 0,
        priority: 1,
        status: 1,
        effective_time: '',
        expiry_time: '',
        condition_rules: [],
        description: '',
        remark: ''
      }
    },

    // 生成默认配置名称：原配置名 + 时间戳
    generateDefaultConfigName(originalName) {
      const now = new Date()
      const year = now.getFullYear()
      const month = String(now.getMonth() + 1).padStart(2, '0')
      const day = String(now.getDate()).padStart(2, '0')
      const hour = String(now.getHours()).padStart(2, '0')
      const minute = String(now.getMinutes()).padStart(2, '0')
      const timeStamp = `${year}${month}${day}${hour}${minute}`
      return `${originalName}_复制_${timeStamp}`
    },

    resetCopyConfigForm() {
      this.$refs.copyConfigForm && this.$refs.copyConfigForm.resetFields()
      this.copyConfigForm = {
        source_config_id: '',
        target_level: '',
        new_config_name: '',
        target_merchant_id: '',
        target_campaign_id: '',
        overwrite: false
      }
      this.targetCampaignList = []
      this.targetMerchantList = []
    },

    resetSearch() {
      this.searchForm = {
        config_type: '',
        status: '',
        effective_start: '',
        effective_end: ''
      }
      this.effectiveDateRange = null
    },

    handleRefresh() {
      console.log('刷新表格数据，当前层级：', this.configLevel, '商户ID：', this.selectedMerchantId, '活动ID：', this.selectedCampaignId)

      // 使用TableComponent的标准refresh方法
      if (this.$refs.configTable && typeof this.$refs.configTable.refresh === 'function') {
        this.$refs.configTable.refresh()
        console.log('调用refresh方法刷新成功')
      } else {
        console.warn('configTable ref或refresh方法不存在，尝试其他方法')

        // 兜底方案1：调用getTableData方法
        if (this.$refs.configTable && typeof this.$refs.configTable.getTableData === 'function') {
          this.$refs.configTable.getTableData()
          console.log('调用getTableData方法刷新成功')
        } else {
          // 兜底方案2：强制重新渲染组件
          console.warn('使用强制更新作为最后的兜底方案')
          this.$forceUpdate()
          this.$nextTick(() => {
            if (this.$refs.configTable) {
              this.$refs.configTable.$forceUpdate()
            }
          })
        }
      }
    },

    // 状态变更处理（列表开关）
    async handleStatusChange(row, done) {
      try {
        const resp = await nfcPointsConfigAPI.batchUpdateConfigs({
          config_ids: [row.id],
          update_data: { status: row.status }
        })
        if (resp.code === 0) {
          // 检查批量操作的实际结果
          const data = resp.data || {}
          if (data.all_success) {
            this.$message.success('状态更新成功')
            done && done(row, true)
          } else if (data.all_failed) {
            this.$message.error(`状态更新失败：${resp.message}`)
            done && done(row, false, resp.message)
          } else {
            // 部分成功或其他情况，单个操作通常是全成功或全失败
            this.$message.success(resp.message || '状态更新完成')
            done && done(row, true)
          }
        } else {
          this.$message.error(resp.message || '状态更新失败')
          done && done(row, false, resp.message)
        }
      } catch (error) {
        done && done(row, false, error.message)
      }
    },

    // 批量启用
    async handleBatchEnable() {
      if (this.selectedConfigs.length === 0) {
        this.$message.warning('请先选择要启用的配置')
        return
      }
      this.$confirm(`确认启用选中的 ${this.selectedConfigs.length} 个配置吗？`, '批量启用', { type: 'warning' })
        .then(async () => {
          const ids = this.selectedConfigs.map(i => i.id)
          const resp = await nfcPointsConfigAPI.batchUpdateConfigs({
            config_ids: ids,
            update_data: { status: 1 }
          })
          if (resp.code === 0) {
            // 检查批量操作的实际结果
            const data = resp.data || {}
            if (data.all_success) {
              this.$message.success('批量启用成功')
            } else if (data.all_failed) {
              this.$message.error(`批量启用失败：${resp.message}`)
            } else if (data.partial_success) {
              this.$message.warning(`部分成功：${resp.message}`)
            } else {
              this.$message.success(resp.message || '批量启用完成')
            }
            this.$refs.configTable.refresh()
          } else {
            this.$message.error(resp.message || '批量启用失败')
          }
        })
    },

    // 批量禁用
    async handleBatchDisable() {
      if (this.selectedConfigs.length === 0) {
        this.$message.warning('请先选择要禁用的配置')
        return
      }
      this.$confirm(`确认禁用选中的 ${this.selectedConfigs.length} 个配置吗？`, '批量禁用', { type: 'warning' })
        .then(async () => {
          const ids = this.selectedConfigs.map(i => i.id)
          const resp = await nfcPointsConfigAPI.batchUpdateConfigs({
            config_ids: ids,
            update_data: { status: 0 }
          })
          if (resp.code === 0) {
            // 检查批量操作的实际结果
            const data = resp.data || {}
            if (data.all_success) {
              this.$message.success('批量禁用成功')
            } else if (data.all_failed) {
              this.$message.error(`批量禁用失败：${resp.message}`)
            } else if (data.partial_success) {
              this.$message.warning(`部分成功：${resp.message}`)
            } else {
              this.$message.success(resp.message || '批量禁用完成')
            }
            this.$refs.configTable.refresh()
          } else {
            this.$message.error(resp.message || '批量禁用失败')
          }
        })
    }
  }
}
</script>

<style scoped>
.page-box {
  padding: 20px;


}

.level-selector-card {
  margin-bottom: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.header-actions {
  display: flex;
  gap: 10px;
}

.level-filter {
  margin-top: 15px;
  display: flex;
  gap: 15px;
}

.config-list-card {
  margin-bottom: 20px;
}

.condition-rules {
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  padding: 15px;
  background-color: #fafafa;
  max-height: 300px;
  overflow-y: auto;
}

.condition-item {
  margin-bottom: 15px;
  padding: 10px;
  background-color: #ffffff;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
}

.condition-item:last-child {
  margin-bottom: 0;
}

.form-tip {
  font-size: 12px;
  color: #909399;
  margin-top: 5px;
}

.template-list {
  max-height: 400px;
  overflow-y: auto;
}

.template-card {
  margin-bottom: 15px;
  cursor: pointer;
  transition: all 0.3s;
}

.template-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.template-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

.template-header h4 {
  margin: 0;
  color: #303133;
}

.template-description {
  color: #606266;
  font-size: 14px;
  margin-bottom: 10px;
  line-height: 1.5;
}

.template-config {
  display: flex;
  gap: 15px;
  font-size: 12px;
  color: #909399;
}

.upload-demo {
  margin: 20px 0;
}
</style>
